#ifndef __SUBSYSTEM_PROJECTILES_H__
#define __SUBSYSTEM_PROJECTILES_H__

#include <list>
#include <vector>
#include <mutex>
#include "Subsystem.hpp"
#include "Game/WorldItem.hpp"

using namespace PocketSurvival::Engine; 


namespace PocketSurvival
{
    struct ComponentCreature;

    class SubsystemPickables;
    class SubsystemBodies;
    class SubsystemTerrain;
    class SubsystemGameInfo;
    class SubsystemBlockBehaviors;
    class SubsystemFireBlockBehavior;
    class SubsystemExplosions;

    class SubsystemProjectiles : public Subsystem
    {
    protected:
        std::vector<Projectile *> m_projectileVec;
        std::vector<Projectile *> m_newProjectileVec;
        std::mutex m_projectilesMutex;
        
        SubsystemPickables *m_pickables;
        SubsystemBodies *m_bodies;
        SubsystemTerrain *m_terrain;
        SubsystemGameInfo *m_gameInfo;
        SubsystemBlockBehaviors *m_blockBehaviors;
        SubsystemFireBlockBehavior *m_fireBlockBehavior;
        SubsystemExplosions *m_explosions;

    public:

        Projectile *addProjectile(int32_t value, const Vector3 &position, const Vector3 &velocity, const Vector3 &angularVelocity, ComponentCreature* owner);
        Projectile *addProjectileNet(int32_t value, const Vector3 &position, const Vector3 &velocity, const Vector3 &angularVelocity, ComponentCreature* owner);
        Projectile *fireProjectile(int32_t value, const Vector3 &position, const Vector3 &velocity, const Vector3 &angularVelocity, ComponentCreature* owner);
        Projectile *fireProjectileNet(int32_t value, const Vector3 &position, const Vector3 &velocity, const Vector3 &angularVelocity, ComponentCreature* owner);

        bool isWater(const Vector3 &position);
        bool isMagma(const Vector3 &position);

    protected:
        void internalSave();

    public:
        SubsystemProjectiles();

        virtual void update(float dt) override;
        virtual void load(const nlohmann::json& json) override;
        virtual void save(nlohmann::json& json) override;
        virtual void saveToMsgJson(nlohmann::json &jsonData) override;

        virtual const std::string& getName() const override;
        virtual SubUpdateType getUpdateType() override;
    };

}

#endif